import json
import random
import threading
import time

import psutil
from pynput import keyboard, mouse
from pynput.keyboard import Key

class GameAutoController:
    def __init__(self):
        # 初始化键盘和鼠标控制器
        self.keyboard_controller = keyboard.Controller()
        self.mouse_controller = mouse.Controller()

        # 控制状态
        self.is_walking = False
        self.walk_direction = None
        self.walk_thread = None

        # 默认按键设置 (可根据游戏调整)
        self.key_mapping = {
            'forward': 'w',
            'backward': 's',
            'left': 'a',
            'right': 'd',
            'jump': Key.space,
            'sprint': Key.shift
        }

        # 游戏进程信息
        self.game_process_name = None
        self.game_window_title = None

    def set_game_info(self, process_name=None, window_title=None):
        """
        设置游戏进程信息
        :param process_name: 游戏进程名称
        :param window_title: 游戏窗口标题
        """
        self.game_process_name = process_name
        self.game_window_title = window_title

    def switch_to_game(self):
        """
        切换到游戏界面
        """
        try:
            # 方法1: 通过进程名查找并激活窗口
            if self.game_process_name:
                for proc in psutil.process_iter(['pid', 'name']):
                    if proc.info['name'] == self.game_process_name:
                        # Windows系统下使用tasklist和wmic命令查找窗口
                        import platform
                        if platform.system() == "Windows":
                            try:
                                # 尝试激活窗口
                                import win32gui
                                import win32con
                                def enum_windows_callback(hwnd, windows):
                                    if win32gui.IsWindowVisible(hwnd):
                                        window_text = win32gui.GetWindowText(hwnd)
                                        if self.game_window_title in window_text if self.game_window_title else self.game_process_name.replace('.exe', '') in window_text:
                                            windows.append(hwnd)
                                    return True

                                windows = []
                                win32gui.EnumWindows(enum_windows_callback, windows)

                                if windows:
                                    hwnd = windows[0]
                                    # 激活窗口
                                    win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
                                    win32gui.SetForegroundWindow(hwnd)
                                    print(f"已切换到游戏窗口: {win32gui.GetWindowText(hwnd)}")
                                    time.sleep(0.5)  # 等待窗口切换完成
                                    return True
                            except ImportError:
                                print("未安装pywin32库，无法自动切换窗口")
                        break
            print("未找到游戏进程，请手动切换到游戏窗口！")
            input("按下任意键后程序会继续执行（请在5秒内切换到游戏窗口）\n"
                  "或关闭窗口退出!")
            time.sleep(5)
            return True

        except Exception as e:
            print(f"切换到游戏界面时出错: {e}")
            return False

    def start_walking(self, direction='forward', duration=None):
        """
        开始行走
        :param direction: 行走方向 ('forward', 'backward', 'left', 'right')
        :param duration: 持续时间(秒)，None表示持续到手动停止
        """
        if self.is_walking:
            self.stop_walking()

        self.is_walking = True
        self.walk_direction = direction
        self.walk_thread = threading.Thread(
            target=self._walk_loop,
            args=(duration,)
        )
        self.walk_thread.daemon = True
        self.walk_thread.start()
        print(f"开始行走: {direction}")

    def _walk_loop(self, duration=None):
        """行走循环"""
        key = self.key_mapping.get(self.walk_direction, self.key_mapping['forward'])

        # 按下对应按键
        self.keyboard_controller.press(key)

        start_time = time.time()
        try:
            while self.is_walking:
                if duration and (time.time() - start_time) >= duration:
                    break
                time.sleep(0.1)
        finally:
            # 释放按键
            self.keyboard_controller.release(key)
            self.is_walking = False
            print("停止行走")

    def stop_walking(self):
        """停止行走"""
        self.is_walking = False
        if self.walk_thread and self.walk_thread.is_alive():
            self.walk_thread.join(timeout=1)

    def walk_in_direction(self, direction, duration=2):
        """朝指定方向行走指定时间"""
        self.start_walking(direction, duration)
        time.sleep(duration + 0.1)  # 等待行走完成

    def random_walk(self, steps=5):
        """随机行走"""
        directions = ['forward', 'backward', 'left', 'right']
        for _ in range(steps):
            direction = random.choice(directions)
            duration = random.randint(1, 3)
            print(f"随机行走: {direction} 持续 {duration:.1f} 秒")
            self.walk_in_direction(direction, duration)
            time.sleep(random.uniform(0.5, 1.5))  # 步间停顿

    def jump(self, times=1):
        """跳跃"""
        for _ in range(times):
            self.keyboard_controller.press(self.key_mapping['jump'])
            time.sleep(0.1)
            self.keyboard_controller.release(self.key_mapping['jump'])
            time.sleep(0.2)

    def sprint_walk(self, direction='forward', duration=3):
        """疾跑行走"""
        # 按住Shift键
        self.keyboard_controller.press(self.key_mapping['sprint'])
        time.sleep(0.1)

        # 行走
        self.walk_in_direction(direction, duration)

        # 释放Shift键
        self.keyboard_controller.release(self.key_mapping['sprint'])

    def mouse_move(self, x_offset, y_offset):
        """
        鼠标相对移动（用于旋转镜头）
        :param x_offset: X轴偏移量（正数向右，负数向左）
        :param y_offset: Y轴偏移量（正数向下，负数向上）
        """
        self.mouse_controller.move(x_offset, y_offset)

    def mouse_move_to(self, x, y):
        """
        将鼠标移动到绝对位置
        :param x: X坐标
        :param y: Y坐标
        """
        self.mouse_controller.position = (x, y)

    def get_mouse_position(self):
        """
        获取当前鼠标位置
        :return: (x, y) 鼠标坐标
        """
        return self.mouse_controller.position

    def rotate_camera(self, horizontal=0, vertical=0, speed=1.0):
        """
        旋转镜头（通过鼠标移动实现）
        :param horizontal: 水平旋转角度（正数向右，负数向左）
        :param vertical: 垂直旋转角度（正数向下，负数向上）
        :param speed: 旋转速度系数
        """
        # 将角度转换为像素移动量（根据游戏灵敏度调整系数）
        x_pixels = int(horizontal * 10 * speed)
        y_pixels = int(vertical * 10 * speed)

        self.mouse_move(x_pixels, y_pixels)

    def rotate_camera_continuous(self, horizontal_speed=0, vertical_speed=0, duration=1):
        """
        持续旋转镜头
        :param horizontal_speed: 水平旋转速度（每秒移动像素数）
        :param vertical_speed: 垂直旋转速度（每秒移动像素数）
        :param duration: 持续时间（秒）
        """
        steps = int(duration * 10)  # 每0.1秒移动一次
        for _ in range(steps):
            self.mouse_move(horizontal_speed * 0.1, vertical_speed * 0.1)
            time.sleep(0.1)

    def hold_right_click_rotate(self, duration=1):
        """
        按住鼠标右键并旋转镜头
        :param duration: 持续时间
        """
        # 按住鼠标右键
        self.mouse_controller.press(mouse.Button.right)
        time.sleep(0.1)  # 等待游戏响应

        # 执行鼠标移动（镜头旋转）
        self.mouse_move(100, 50)  # 示例：向右下角旋转

        time.sleep(duration)  # 保持旋转

        # 释放鼠标右键
        self.mouse_controller.release(mouse.Button.right)

    def rotate_camera_with_right_click(self, x_offset, y_offset, duration=0.5):
        """
        按住右键并旋转镜头到指定位置
        :param x_offset: X轴偏移
        :param y_offset: Y轴偏移
        :param duration: 持续时间
        """
        # 按住鼠标右键
        self.mouse_controller.press(mouse.Button.right)
        time.sleep(0.05)

        # 移动鼠标旋转镜头
        self.mouse_move(x_offset, y_offset)
        time.sleep(duration)

        # 释放鼠标右键
        self.mouse_controller.release(mouse.Button.right)
    def look_at_angle(self, angle, speed=1.0):
        """
        向指定角度观看（水平方向）
        :param angle: 角度（度），正数向右，负数向左
        :param speed: 旋转速度
        """
        self.rotate_camera(horizontal=angle, speed=speed)

    def look_up_down(self, angle, speed=1.0):
        """
        上下观看
        :param angle: 角度（度），正数向下，负数向上
        :param speed: 旋转速度
        """
        self.rotate_camera(vertical=angle, speed=speed)

    def mouse_click(self, button='left', clicks=1):
        """鼠标点击"""
        btn = mouse.Button.left if button == 'left' else mouse.Button.right
        self.mouse_controller.click(btn, clicks)

    def look_around(self):
        """环顾四周"""
        # 随机移动鼠标模拟观察
        for _ in range(5):
            x_move = random.randint(-100, 100)
            y_move = random.randint(-50, 50)
            self.mouse_move(x_move, y_move)
            time.sleep(0.5)

    def smooth_camera_rotation(self, x_offset, y_offset, steps=10, step_delay=0.05):
        """
        平滑旋转镜头（按住右键）
        :param x_offset: X总偏移量
        :param y_offset: Y总偏移量
        :param steps: 分步次数
        :param step_delay: 每步延迟
        """
        # 按住鼠标右键
        # self.mouse_controller.press(mouse.Button.right)
        # time.sleep(0.1)

        # 分步移动实现平滑旋转
        x_step = x_offset / steps
        y_step = y_offset / steps

        for i in range(steps):
            self.mouse_move(x_step, y_step)
            time.sleep(step_delay)

        # 释放鼠标右键
        # self.mouse_controller.release(mouse.Button.right)

    def start(self,interval = 3.5):
        time.sleep(1)  # 等待切换完成
        self.keyboard_execute('e')
        time.sleep(interval) # 间隔时间 e-> 退出
        self.keyboard_execute(Key.esc)
        time.sleep(1)
    def auto_play_sequence(self, sequence):
        """
        执行自动游戏序列
        :param sequence: 操作序列列表
        """

        # 执行操作序列
        for action in sequence:
            print(f"执行操作: {action}")
            # 准备
            if action['type'] == 'prepare':
                self.start(interval = action.get('interval', 3.5))
            # 走
            if action['type'] == 'walk':
                self.walk_in_direction(action['direction'], action.get('duration', 2))
            # 跳跃
            elif action['type'] == 'jump':
                self.jump(action.get('times', 1))
            # 疾跑
            elif action['type'] == 'sprint':
                self.sprint_walk(action['direction'], action.get('duration', 3))
            # 等待
            elif action['type'] == 'wait':
                time.sleep(action.get('duration', 1))
            # 鼠标移动
            elif action['type'] == 'mouse_move':
                self.mouse_move(action['x_offset'], action['y_offset'])
            # 镜头旋转
            elif action['type'] == 'rotate_camera':
                self.rotate_camera(
                    action.get('horizontal', 0),
                    action.get('vertical', 0),
                    action.get('speed', 1.0)
                )
            # 持续镜头旋转
            elif action['type'] == 'rotate_camera_continuous':
                self.rotate_camera_continuous(
                    action.get('horizontal_speed', 0),
                    action.get('vertical_speed', 0),
                    action.get('duration', 1)
                )
            # 鼠标点击
            elif action['type'] == 'click':
                self.mouse_click(action.get('button', 'left'), action.get('clicks', 1))
            # 镜头旋转并点击
            elif action['type'] == 'rotate_camera_with_right_click':
                self.rotate_camera_with_right_click(
                    action.get('x_offset', 0),
                    action.get('y_offset', 0),
                    action.get('duration', 0.5)
                )
            elif action['type'] == 'smooth_camera_rotation':
                self.smooth_camera_rotation(
                    action.get('x_offset', 0),
                    action.get('y_offset', 0),
                    action.get('steps', 10),
                    action.get('step_delay', 0.05)
                )
            elif action['type'] == 'shapeshift':
                self.shapeshift(
                    action.get('interval', 1.5),
                )
    def stop_all(self):
        """停止所有操作"""
        self.stop_walking()
        print("所有操作已停止")

    def keyboard_execute(self,key):
        self.keyboard_controller.press(key)
        time.sleep(0.2)
        self.keyboard_controller.release(key)
        time.sleep(0.2)

    def shapeshift(self, interval = 1.5):
        self.keyboard_execute('4')
        time.sleep(interval)
        self.keyboard_execute('4')


    def finish(self):
        print('使用缩地青符,返回土地庙.')
        time.sleep(8)
        self.keyboard_execute('q')


def main(loop_count , loop_wait_duration, game_process_name, game_window_title, action_sequence):
    print("3秒后开始自动操作...")   
    time.sleep(3)
    # 创建控制器实例
    controller = GameAutoController()
    # 设置游戏信息（根据实际情况修改）
    controller.set_game_info(process_name=game_process_name, window_title=game_window_title)
    # 切换到游戏
    controller.switch_to_game()

    try:
        for i in range(loop_count):
            print(f'正在执行第{i+1}次任务。')
            # 执行自动游戏序列
            controller.auto_play_sequence(action_sequence)
            # 执行完成，返回
            controller.finish()
            # 等待三十秒
            print(f'本次任务完成,等待时间{loop_wait_duration}s后，开启下一轮。')
            time.sleep(loop_wait_duration)
    except KeyboardInterrupt:
        print("\n用户中断操作")
    finally:
        controller.stop_all()
        print("程序结束")
        input("按任意键退出...")
# 使用示例
if __name__ == "__main__":
    # 读取 JSON 配置文件
    try:
        with open("config.json", "r", encoding="utf-8") as f:
            config = json.load(f)
        loop_count = config.get('loop_count', 1)  # 如果没有设置loop_count，默认为1
        loop_wait_duration= config.get('loop_wait_duration', 30) # 如果没有设置loop_wait_duration，默认为5
        game_process_name = config.get('game_process_name', 'b1-Win64-Shipping.exe') # 如果没有设置game_process_name，默认为b1-Win64-Shipping.exe
        game_window_title = config.get('game_window_title', 'b1')
        action_sequence = config.get('action_sequence', [])
        print("配置信息：", config)
        main(loop_count , loop_wait_duration, game_process_name, game_window_title, action_sequence)
    except FileNotFoundError:
        print("未找到配置文件 config.json")
    except json.JSONDecodeError:
        print("配置文件格式错误，请检查 JSON 格式")



